package pub.cleangao.memm.transport;


import lombok.extern.slf4j.Slf4j;
import pub.cleangao.memm.exception.RpcErrorMessage;
import pub.cleangao.memm.exception.RpcException;
import pub.cleangao.memm.registry.RpcRuntime;
import pub.cleangao.memm.registry.RpcServiceRegistry;
import pub.cleangao.memm.transport.message.RpcRequest;
import java.lang.reflect.Method;


@Slf4j
public class RpcRequestHandler {

    private final RpcServiceRegistry serviceRegistry;

    public RpcRequestHandler() {
        serviceRegistry = RpcRuntime.getRegistry();
    }

    /**
     * Processing rpcRequest: call the corresponding method, and then return the method
     */
    public Object handle(RpcRequest rpcRequest) {
        Object service = serviceRegistry.getServiceImpl(rpcRequest);
        if (service == null) {
            throw new RpcException(RpcErrorMessage.SERVICE_NOT_FOUND);
        }
        return invokeTargetMethod(rpcRequest, service);
    }

    /**
     * get method execution results
     *
     * @param rpcRequest client request
     * @param service    service object
     * @return the result of the target method execution
     */
    private Object invokeTargetMethod(RpcRequest rpcRequest, Object service) {
        try {
            Method method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
            return method.invoke(service, rpcRequest.getParameters());
        } catch (Exception e) {
            throw new RpcException(e);
        }

    }
}
